package br.com.ds3.controller;

import java.io.File;
import java.util.Date;
import java.util.List;

import org.hibernate.criterion.Order;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.interceptor.download.Download;
import br.com.caelum.vraptor.interceptor.download.FileDownload;
import br.com.caelum.vraptor.view.Results;
import br.com.ds3.annotation.Permission;
import br.com.ds3.dao.AtividadeDAO;
import br.com.ds3.dao.EventoDAO;
import br.com.ds3.dao.InscricaoDAO;
import br.com.ds3.dao.UsuarioDAO;
import br.com.ds3.model.Evento;
import br.com.ds3.model.Inscricao;
import br.com.ds3.model.Perfil;
import br.com.ds3.model.Usuario;
import br.com.ds3.rule.BoletoRule;
import br.com.ds3.session.UserSession;

@Resource
public class InscricaoController {
	private final InscricaoDAO inscricaoDAO;
	private final Result result;
	private final UserSession userSession;
	private final EventoDAO eventoDAO;
	private final AtividadeDAO atividadeDAO;
	
	public InscricaoController(InscricaoDAO inscricaoDAO, Result result, UserSession userSession, EventoDAO eventoDAO, AtividadeDAO atividadeDAO) {
		this.inscricaoDAO = inscricaoDAO;
		this.result = result;
		this.userSession = userSession;
		this.eventoDAO = eventoDAO;
		this.atividadeDAO = atividadeDAO;

	}
	
    @Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
    public void pesquisa(Long idEvento, Long pagina) {
    	pagina = pagina == null ? 1L : pagina;
    	Evento evento = (idEvento == null ? null : eventoDAO.get(idEvento));
        Long paginas = inscricaoDAO.countPaginas(null, evento, false);
        List<Inscricao> inscricoes = inscricaoDAO.pesquisa(null, evento, true, pagina, Order.asc("e.nome"), Order.asc("p.nome"));
        List<Evento> eventos = eventoDAO.pesquisa(null, null);
        
        result.include("idEvento", idEvento);
        result.include("pagina", pagina);
        result.include("paginas", paginas);
        result.include("eventos", eventos);
        result.include("inscricoes", inscricoes);
    }
	
	@Post
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
	public void grava(Inscricao inscricao) {	
		inscricaoDAO.save(inscricao);
		result.use(Results.json()).withoutRoot().from(inscricao).serialize();
	}
	
	@Post
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
	public void cadastro(Inscricao inscricao) {
		List<Evento> eventos = eventoDAO.listaProximosEventos();
		
		result.include("inscricao", inscricao);
		result.include("eventos", eventos);
		
		if (inscricao == null || inscricao.getParticipante() == null) {
			List<Usuario> participantes = new UsuarioDAO().pesquisa(null, null);
			result.include("participantes", participantes);
		}
	}
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
    public void altera(Long id) {
    	Inscricao inscricao = inscricaoDAO.get(id);
    	result.forwardTo(this).cadastro(inscricao);
    }
    
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
    public void inclui() {	
    	result.forwardTo(this).cadastro(null);
    }
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
	public void inscricaoParticipante(Long idEvento, Long idAtividade) {
		Inscricao inscricao = new Inscricao();
		inscricao.setParticipante(userSession.getUser());
		inscricao.setEvento(eventoDAO.get(idEvento));
		inscricao.setAtividade(atividadeDAO.get(idAtividade));
		result.forwardTo(this).cadastro(inscricao);
	}
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
	public Download gerarBoleto(Long id) {
		Inscricao inscricao = inscricaoDAO.get(id);
		
		File file = BoletoRule.geraBoletoInscricao(inscricao);
		String filename = "boleto" + inscricao.getId().toString() + ".pdf";
		String contentType = "application/pdf";
		
		return new FileDownload(file, contentType, filename);
	}
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })
	public void cancelar(Long id) {
		Inscricao inscricao = inscricaoDAO.get(id);
		inscricao.setDataCancelamento(new Date());
		inscricaoDAO.save(inscricao);
		result.use(Results.json()).withoutRoot().from(inscricao).serialize();
	}
	
	@Get("/inscricao/participanteJaInscrito")
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })	
	public void participanteJaInscrito(Long idEvento, Long idAtividade, Long idParticipante) {		
    	String retorno = "0";
    	if(inscricaoDAO.pesquisaCompleta(idParticipante, idEvento, idAtividade).size() != 0) retorno = "1";
    	result.use(Results.json()).withoutRoot().from(retorno).serialize();		
	}
	
	@Get("/inscricao/vagaDisponivel")
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE, Perfil.PARTICIPANTE })	
	public void vagaDisponivel(Long idEvento, Long idAtividade) {		
		Long vagasIniciais = atividadeDAO.get(idAtividade).getNumeroVagas();
		Long inscricoes    = inscricaoDAO.getNumeroInscricoes(idEvento, idAtividade);
		String retorno = "0";
		if(vagasIniciais.longValue() <= inscricoes.longValue()) retorno = "1";		
		result.use(Results.json()).withoutRoot().from(retorno).serialize();		
	}		
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE})
	public void pagar(Long id) {
		Inscricao inscricao = inscricaoDAO.get(id);
		inscricao.setDataPagamento(new Date());
		inscricaoDAO.save(inscricao);
		result.use(Results.json()).withoutRoot().from(inscricao).serialize();
	}
	
	@Get
	@Permission(value = { Perfil.ADMINISTRADOR, Perfil.ATENDENTE})
	public void exclui(Long id) {
		Inscricao inscricao = inscricaoDAO.get(id);
		inscricaoDAO.delete(inscricao);
		result.use(Results.json()).withoutRoot().from(inscricao).serialize();
	}
}
